package com.yans.views.display
{ 
	import com.yans.GlobalAPICore;
	import com.yans.interfaces.IFish;
	
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.filters.GlowFilter;
	import flash.geom.Point;
	import flash.geom.Rectangle; 
	import flash.utils.getTimer;
	
	
	
	public class BitmapMovie extends Sprite implements IFish
	{
		public static const MOVIE_MOVE:String = "BitmapMovie.MOVIE_MOVE";
		
		private static var _white:GlowFilter = new GlowFilter(0xffffff, 1, 6, 6, 5);
		private var _data:BitmapFrameData;
		private var _bd:BitmapData, count:int = 0; 
		private var _bmp:Bitmap, p:Point, sqr:int;
		private var _rect:Rectangle;
		
		private var _frames:Array;
		private var _isUserDefined:Boolean;
		
		public function get target():Object {
			return _frames;
		}
		
		/**
		 *	自设帧 
		 * @param obj 数组
		 */		
		public function set target(obj:Object):void {
			if(!obj && _data) {
				_isUserDefined = false;
				_frames = [];
				for(var i:int = 0; i < _data.pointArr.length; i++) {
					_frames.push(i);
				}
			}
			else {
				_frames = obj as Array;	
			}
			trace("#Frames", _frames);
		} 
		
		public function get isUserDefined():Boolean {
			return _isUserDefined;
		}
		
		public function BitmapMovie(data:BitmapFrameData = null) {
			init(data);
		}
		
		public function play():void {
			if(!_data) return;
			//			count = 0;
			this.addEventListener(Event.ENTER_FRAME, onEnterFrame);
		}
		
		public function get isPlaying():Boolean {
			return this.hasEventListener(Event.ENTER_FRAME);
		}
		
		public function stop():void {
			if(!_data) return;
			this.removeEventListener(Event.ENTER_FRAME, onEnterFrame);
		}
		
		public function get code():int { 
			return 0;
		}
		
		public function dispose():void {
			stop();
			if(this.parent) this.parent.removeChild(this);
			_data = null;
			if(_bd) _bd.dispose();
			_bd = null;
			_bmp = null;
		}
		
		public function isOver(x:int, y:int):Boolean {
			if(!_bd) {
				dispose();
				return false;
			}
			return _bd.getPixel(x - _bmp.x, y - _bmp.y) > 0;
		}
		
		public function clone():BitmapMovie {
			var mc:BitmapMovie = new BitmapMovie(_data);
			return mc;
		}
		
		public function init(data:Object):void {
			if(!data) return;
			_data = data as BitmapFrameData;
			_bd = new BitmapData(_data.offsetRect.width, _data.offsetRect.height, true, 0);
			_bmp = new Bitmap(_bd);
			addChild(_bmp);
			sqr = int(_data.bitmapData.width / _data.offsetRect.width); 
			_bd.fillRect(_bd.rect, 0);
			_bmp.smoothing = true;
			target = _data.frames;
			graphics.beginFill(0xff0000, 1);
			graphics.drawCircle(0, 0, 2);
			graphics.endFill();
			
			this.addEventListener(MouseEvent.MOUSE_OVER, onMouseOver);
			this.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
		}
		
		public function nextFrame():void { 
			//			if(isPlaying) return;
			stop();
			render();
			nextCount();
		}
		
		private function nextCount():void { 
			count = count >= (_frames.length - 1) ? 0 : count + 1;
		}
		
		private function render():void { 
			var frame:int = int(_frames[count]);
			if(frame < 0 || frame >= _frames.length || !_frames[frame]) {
				nextCount();
				render();
				return;
			}
			p = _data.pointArr[frame] as Point;
			if(!p) {
				nextCount();
				render();
				return;
			}
			_bmp.x = p.x - _data.offsetRect.x;
			_bmp.y = p.y - _data.offsetRect.y; 
			_bd.fillRect(_bd.rect, 0);
			_rect = new Rectangle(int(frame % sqr) * _data.offsetRect.width, int(frame / sqr) * _data.offsetRect.height, _data.offsetRect.width, _data.offsetRect.height);
			_bd.copyPixels(_data.bitmapData, _rect, new Point(0, 0));
		}
		
		private function onEnterFrame(e:Event):void {
			render();
			nextCount();
		}
		
		private function onMouseOver(e:MouseEvent):void {
			this.addEventListener(MouseEvent.MOUSE_OUT, onMouseOut);
			GlobalAPICore.river.addFish(this);
			lTime = getTimer();
		}
		
		private function onMouseOut(e:MouseEvent):void {
			this.removeEventListener(MouseEvent.MOUSE_OUT, onMouseOut);
			GlobalAPICore.river.removeFish(this);
			if(!_bmp) return;
			_bmp.filters = [];
		}
		
		private function onMouseDown(e:MouseEvent):void {
			this.stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
			this.startDrag();
		}
		
		private function onMouseUp(e:MouseEvent):void {
			this.stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp);
			this.stopDrag();
			dispatchEvent(new Event(MOVIE_MOVE));
		}
		
		private var lTime:uint; 
		
		public function getBitmapData():BitmapData {
			return _data.bitmapData;
		}
		
		public function swim(times:int, dt:Number=0.04):void
		{
			if(!_bmp) {
				dispose();
				return;
			}
			if(getTimer() - lTime > 200) { 
				lTime = getTimer();
				if(isOver(this.mouseX, this.mouseY)) {
					_bmp.filters = [_white];
				}
				else {
					_bmp.filters = [];
				}
			} 
		}
		
	}
}